		TITLE	PE_SECT - Copyright (C) SLR Systems 1994

		INCLUDE	MACROS

if	fg_pe
		INCLUDE	SEGMENTS
		INCLUDE	SECTIONS
		INCLUDE	PE_STRUC
		INCLUDE	IO_STRUC
		INCLUDE	EXES
		INCLUDE	SYMBOLS
		INCLUDE	SEGMSYMS

		PUBLIC	ASSIGN_PE_SECTIONS,DO_OBJECT_ALIGN,DEFIMPS


		.DATA

		EXTERNDEF	MODULE_NAME:BYTE

		EXTERNDEF	ENTRYNAME_BITS:DWORD,CURN_SECTION_GINDEX:DWORD,HIGHEST_ORDINAL:DWORD,LOWEST_ORDINAL:DWORD
		EXTERNDEF	N_EXPORTS:DWORD,N_IMPORTS_REFERENCED:DWORD,N_EXPORTS_BYNAME:DWORD,SEG_PAGE_SIZE_M1:DWORD
		EXTERNDEF	NOT_SEG_PAGE_SIZE_M1:DWORD,SYMBOL_LENGTH:DWORD,_OUTFILE_GINDEX:DWORD,EXPORT_ORDINAL_BASE:DWORD
		EXTERNDEF	N_EXPORT_RVAS:DWORD,FIRST_CODE_DATA_OBJECT_GINDEX:DWORD,FIRST_CODE_DATA_OBJECT_NUMBER:DWORD
		EXTERNDEF	N_CODE_DATA_OBJECTS:DWORD,PE_EXPORTS_OBJECT_GINDEX:DWORD,PE_EXPORTS_OBJECT_NUMBER:DWORD
		EXTERNDEF	PE_IMPORTS_OBJECT_GINDEX:DWORD,PE_IMPORTS_OBJECT_NUMBER:DWORD,PE_RSRC_OBJECT_GINDEX:DWORD
		EXTERNDEF	PE_RSRC_OBJECT_NUMBER:DWORD,N_MODULES_REFERENCED:DWORD,ICODE_SEGMOD_GINDEX:DWORD
		EXTERNDEF	ICODE_PEOBJECT_NUMBER:DWORD,ICODE_SM_BASE_SEG_GINDEX:DWORD,ICODE_OS2_FLAGS:DWORD
		EXTERNDEF	PE_FIXUP_OBJECT_GINDEX:DWORD,PE_FIXUP_OBJECT_NUMBER:DWORD,PE_DEBUG_OBJECT_GINDEX:DWORD
		EXTERNDEF	PE_DEBUG_OBJECT_NUMBER:DWORD,PE_OBJECT_ALIGN:DWORD,PE_FIRST_OBJECT_RVA:DWORD,FINAL_HIGH_WATER:DWORD
		EXTERNDEF	FORWARDER_TEXT_SIZE:DWORD,EXPORT_TEXT_SIZE:DWORD,PE_EXEHDR_START:DWORD,FIRST_OBJECT_FILE_ADDR:DWORD
		EXTERNDEF	NEXT_OBJECT_FILE_ADDR:DWORD,PE_NEXT_OBJECT_RVA:DWORD,PE_NEXT_SECTION_HDR:DWORD,OMF_NAME:DWORD
		EXTERNDEF	EXPORT_RVA_SIZE:DWORD,NAME_TEXT_SIZE:DWORD,MODNAM_TEXT_SIZE:DWORD,ICODE_SM_START:DWORD
		EXTERNDEF	FIRST_PEOBJECT_GINDEX:DWORD,LAST_PEOBJECT_GINDEX:DWORD,LAST_PEOBJECT_NUMBER:DWORD
		EXTERNDEF	FIRST_IMPMOD_GINDEX:DWORD,FIRST_SECTION_GINDEX:DWORD,ICODE_PEOBJECT_GINDEX:DWORD
		EXTERNDEF	tls_CLASS_GINDEX:DWORD

		EXTERNDEF	SECTION_GARRAY:STD_PTR_S,SEGMOD_GARRAY:STD_PTR_S,SEGMENT_GARRAY:STD_PTR_S,OUTFILE_GARRAY:STD_PTR_S
		EXTERNDEF	_FILE_LIST_GARRAY:STD_PTR_S,PE_OBJECT_GARRAY:STD_PTR_S,IMPMOD_GARRAY:STD_PTR_S
		EXTERNDEF	SYMBOL_GARRAY:STD_PTR_S,IMPNAME_GARRAY:STD_PTR_S,RC_LIST:FILE_LISTS,PEXEHEADER:PEXE


		.CODE	MIDDLE_TEXT

		EXTERNDEF	INIT_NEW_SECTION:PROC,SETUP_OUTFILE:PROC,HANDLE_PAUSE:PROC,SEGM_OUT_INIT:PROC


ASSIGN_PE_SECTIONS	PROC
		;
		;ASSIGN SOME SECTION #'S
		;
		;FIRST POSSIBLE SECTION IS .edata
		;
		XOR	EAX,EAX			;CURRENT PE_SECT

		MOV	FIRST_PEOBJECT_GINDEX,EAX
		MOV	LAST_PEOBJECT_GINDEX,EAX

		MOV	LAST_PEOBJECT_NUMBER,EAX

		CMP	ENTRYNAME_BITS,EAX	;FIRST, IS THERE AN EXPORT SECTION?
		JZ	L01$

		CALL	GET_NEW_OBJECT		;RETURNS # IN EAX, GINDEX IN ECX

		MOV	PE_EXPORTS_OBJECT_NUMBER,EAX
		MOV	PE_EXPORTS_OBJECT_GINDEX,ECX
L01$:
		CMP	FIRST_IMPMOD_GINDEX,0
		JZ	L02$

		CALL	GET_NEW_OBJECT		;THERE ARE IMPORTS

		MOV	PE_IMPORTS_OBJECT_NUMBER,EAX
		MOV	PE_IMPORTS_OBJECT_GINDEX,ECX
L02$:
		;
		;SCAN SEGMOD LIST FROM SECTION 1, ASSIGN SEGMODS TO 'PE_SECTIONS'
		;BASED ON PACKCODE, PACKDATA, OS2_FLAGS,
		;DETERMINE HEADER SIZE FROM PE_SECTION COUNT
		;DETERMINE STARTING RVA FOR SECTIONS FROM HEADER SIZE
		;
		PUSH	EBP
		MOV	ESI,FIRST_SECTION_GINDEX

		CONVERT	ESI,ESI,SECTION_GARRAY
		ASSUME	ESI:PTR SECTION_STRUCT

		MOV	ESI,[ESI]._SECT_FIRST_SEGMOD_GINDEX
		XOR	ECX,ECX			;CURRENT BASE SEGMENT

		MOV	EBX,-1			;CURRENT RELEVANT OS2_FLAGS - FORCE MISMATCH
		XOR	EBP,EBP			;CURRENT GROUP

		MOV	EDX,EBX			;CURRENT NONZERO FLAGS
L1$:
		MOV	CURN_SEGMOD,ESI
		CONVERT	ESI,ESI,SEGMOD_GARRAY
		ASSUME	ESI:PTR SEGMOD_STRUCT
		MOV	EDI,[ESI]._SM_BASE_SEG_GINDEX

		CMP	EDI,ECX
		MOV	ESI,[ESI]._SM_NEXT_SEGMOD_GINDEX

		MOV	ECX,EDI
		JZ	L9$			;SKIP IF BASE SEGMENT MATCHES

		PUSH	ESI
		CONVERT	EDI,EDI,SEGMENT_GARRAY
		ASSUME	EDI:PTR SEGMENT_STRUCT
		MOV	EAX,[EDI]._SEG_CLASS_GINDEX

		MOV	ESI,tls_CLASS_GINDEX
		GETT	DH,DOING_tls

		CMP	ESI,EAX
		JZ	GOT_tls

		TEST	DH,DH
		JNZ	END_tls

		MOV	EAX,[EDI]._SEG_OS2_FLAGS

		AND	EAX,MASK SR_EO_RO + MASK SR_SHARED + MASK SR_TYPE
		GETT	DH,PACKCODE_FLAG

		CMP	EBX,EAX
		JNZ	L5$			;CRITICAL FLAGS CHANGE

		CMP	[EDI]._SEG_GROUP_GINDEX,EBP
		JZ	L6$			;PACK IF GROUP MATCHES

		TEST	AL,1
		JZ	L3$

		GETT	DH,PACKDATA_FLAG
L3$:
		OR	DH,DH
		JNZ	L6$
L5$:
		;
		;LOOKS LIKE WE NEED TO CHANGE SECTIONS...
		;
		TEST	DL,MASK SEG32_NONZERO
		JZ	L6$			;DON'T CHANGE IF SECTION IS ZERO-LENGTH SO FAR

		MOV	EBX,EAX			;NEW FLAGS
		PUSH	ECX

		CALL	GET_NEW_OBJECT

		MOV	EDX,FIRST_CODE_DATA_OBJECT_NUMBER
		MOV	EBP,[EDI]._SEG_GROUP_GINDEX

		TEST	EDX,EDX
		JZ	L7$
L71$:
		XOR	DL,DL			;NEW OBJECT IS ZERO-LENGTH
		MOV	EAX,CURN_SEGMOD

		POP	ECX
		MOV	LAST_SEGMOD,EAX
L6$:
		MOV	EAX,LAST_PEOBJECT_NUMBER
		MOV	ESI,LAST_PEOBJECT_GINDEX

		MOV	[EDI]._SEG_PEOBJECT_NUMBER,EAX
		MOV	[EDI]._SEG_PEOBJECT_GINDEX,ESI

		OR	DL,[EDI]._SEG_32FLAGS
		POP	ESI
L9$:
		TEST	ESI,ESI
		JNZ	L1$

		JMP	L90$

GOT_tls:
		TEST	DH,DH
		JNZ	L6$

		SETT	DOING_tls
GOT_tls_1:
		MOV	EAX,[EDI]._SEG_OS2_FLAGS

		AND	EAX,MASK SR_EO_RO + MASK SR_SHARED + MASK SR_TYPE
		JMP	L5$

END_tls:
		RESS	DOING_tls

		JMP	GOT_tls_1

L7$:
		MOV	FIRST_CODE_DATA_OBJECT_NUMBER,EAX
		MOV	FIRST_CODE_DATA_OBJECT_GINDEX,ECX

		JMP	L71$

L90$:
		;
		;CLEAN UP IF LAST OBJECT IS ZERO-LENGTH
		;
		TEST	DL,MASK SEG32_NONZERO

		POP	EBP
		JNZ	L91$

		MOV	EAX,LAST_SEGMOD
		CALL	FIX_ENDING_NUL
L91$:
		MOV	EAX,LAST_PEOBJECT_NUMBER

		SUB	EAX,FIRST_CODE_DATA_OBJECT_NUMBER

		INC	EAX

		MOV	N_CODE_DATA_OBJECTS,EAX
		;
		;OTHER POSSIBLE PE_SECTIONS ARE:
		;	.idata
		;	.tls
		;	.rsrc
		;	.reloc
		;	.debug
		;
		BITT	RC_SUPPLIED
		JZ	L92$

		MOV	EAX,RC_LIST.FILE_FIRST_GINDEX
		CONVERT	EAX,EAX,_FILE_LIST_GARRAY
		ASSUME	EAX:PTR FILE_LIST_STRUCT

		MOV	EAX,[EAX].FILE_LIST_NEXT_GINDEX

		TEST	EAX,EAX
		JZ	L92$

		CALL	GET_NEW_OBJECT		;ASSUME THERE ARE RESOURCES

		MOV	PE_RSRC_OBJECT_NUMBER,EAX
		MOV	PE_RSRC_OBJECT_GINDEX,ECX
L92$:
		BITT	PE_BASE_FIXED
		JNZ	L94$

		CALL	GET_NEW_OBJECT		;ASSUME THERE ARE FIXUPPS

		MOV	PE_FIXUP_OBJECT_NUMBER,EAX
		MOV	PE_FIXUP_OBJECT_GINDEX,ECX
L94$:
;		BITT	CODEVIEW_FLAG
;		JZ	L95$

		CALL	GET_NEW_OBJECT		;THERE IS A DEBUG SECTION

		MOV	PE_DEBUG_OBJECT_NUMBER,EAX
		MOV	PE_DEBUG_OBJECT_GINDEX,ECX
L95$:
		MOV	EAX,LAST_PEOBJECT_NUMBER

		MOV	PEXEHEADER._PEXE_N_OBJECTS,AX
		;
		;HOW BIG DO YOU GUESS THE HEADER WILL BE?  BETTER JUST CREATE IT...
		;
		CALL	GET_MOVE_SIZE_STUB	;PARAGRAPH ALIGNED...

		MOV	PE_EXEHDR_START,EAX	;FILE ADDRESS OF PE HEADER
		ADD	EAX,SIZEOF PEXE		;SIZE OF PE HEADER

		MOV	PE_NEXT_SECTION_HDR,EAX	;FILE ADDRESS OF NEXT SECTION HEADER
		MOV	EBX,EAX

		MOV	EAX,SIZE PE_OBJECT_STRUCT

		MUL	LAST_PEOBJECT_NUMBER	;SIZE OF OBJECT HEADERS

		ADD	EAX,EBX			;END OF HEADERS

		MOV	FINAL_HIGH_WATER,EAX

		DO_FILE_ALIGN_EAX

		MOV	PEXEHEADER._PEXE_HEADER_SIZE,EAX
		CALL	DO_OBJECT_ALIGN

		MOV	PE_NEXT_OBJECT_RVA,EAX

		CMP	ENTRYNAME_BITS,0
		JZ	L109$
		;
		;ADJUST STUFF FOR .edata OBJECT
		;
		CALL	FIX_DLLNAME

		MOV	ESI,PE_EXPORTS_OBJECT_GINDEX
		CONVERT	ESI,ESI,PE_OBJECT_GARRAY
		ASSUME	ESI:PTR PE_OBJECT_STRUCT

		MOV	DPTR [ESI]._PEOBJECT_NAME,'ade.'

		MOV	DPTR [ESI]._PEOBJECT_NAME+4,'at'

		MOV	EBX,SYMBOL_LENGTH

		ADD	EBX,SIZE PE_EXPORT_DIR_STRUCT+1	;NUL FROM DLLNAME...
		MOV	EAX,HIGHEST_ORDINAL

		MOV	EXPORT_ORDINAL_BASE,1

		OR	EAX,EAX
		JZ	L101$			;NONE EXPORTED BY ORDINAL, USE N_EXPORTS

		SUB	EAX,LOWEST_ORDINAL

		INC	EAX

		CMP	N_EXPORTS,EAX
		JA	L103$

		MOV	EDX,LOWEST_ORDINAL	;# EXPORTS IS <=  (HIGHEST-LOWEST)

		MOV	EXPORT_ORDINAL_BASE,EDX	;SO USE LOWEST AS BASE
		JMP	L102$

L103$:
		;
		;MORE EXPORTS NEEDED THAN HIGHEST-LOWEST, CALCULATE BASE
		;
		MOV	EAX,N_EXPORTS
		MOV	EDX,HIGHEST_ORDINAL

		SUB	EDX,EAX
		JBE	L102$

		MOV	EXPORT_ORDINAL_BASE,EDX	;SO USE LOWEST AS BASE
L101$:
		MOV	EAX,N_EXPORTS
L102$:
		MOV	N_EXPORT_RVAS,EAX	;SLOTS WE WILL FILL...

		SHL	EAX,2			;TOTAL SIZE OF EXPORT RVA VECTOR

		MOV	EXPORT_RVA_SIZE,EAX
		ADD	EBX,EAX

		MOV	EAX,6
		MUL	N_EXPORTS_BYNAME	;TOTAL SIZE OF NAME_POINTERS AND ORDINAL TABLE

		ADD	EAX,EBX

		ADD	EAX,EXPORT_TEXT_SIZE

		ADD	EAX,FORWARDER_TEXT_SIZE

		MOV	PEXEHEADER._PEXE_EXPORT_SIZE,EAX

		DO_FILE_ALIGN_EAX

		MOV	[ESI]._PEOBJECT_VSIZE,EAX

		CALL	DO_OBJECT_ALIGN

		MOV	EBX,PE_NEXT_OBJECT_RVA

		MOV	[ESI]._PEOBJECT_RVA,EBX
		ADD	EAX,EBX

		MOV	PEXEHEADER._PEXE_EXPORT_RVA,EBX
		MOV	PE_NEXT_OBJECT_RVA,EAX
L109$:

		JMP	SIZE_IMPORTS_OBJECT

ASSIGN_PE_SECTIONS	ENDP


DO_OBJECT_ALIGN	PROC
		;
		;
		;
		PUSH	ECX
		MOV	ECX,PE_OBJECT_ALIGN

		DEC	ECX

		ADD	EAX,ECX
		XOR	ECX,-1

		AND	EAX,ECX
		POP	ECX

		RET

DO_OBJECT_ALIGN	ENDP


GET_MOVE_SIZE_STUB	PROC	NEAR
		;
		;PE MUST PROCESS OLD FIRST, THEN HANDLE STUB
		;
		MOV	EAX,FIRST_SECTION_GINDEX

		MOV	CURN_SECTION_GINDEX,EAX
		CALL	HANDLE_PAUSE		;IF FIRST SECTION, MAYBE PAUSE
		;
		;'OLD' PROCESSING?
		;
;		SETT	STUB_PROCESSING
		BITT	OLD_SUPPLIED		;MUST PROCESS 'OLD' FIRST
		JZ	L2$			;IN CASE IT'S SAME AS NEW .EXE
;		CALL	PROCESS_OLD_PE
L2$:
		CALL	SETUP_OUTFILE		;

		CALL	INIT_NEW_SECTION	;

		CALL	SEGM_OUT_INIT		;ACTUALLY MOVES STUB FILE

		MOV	EAX,FINAL_HIGH_WATER

		RET

GET_MOVE_SIZE_STUB	ENDP


FIX_DLLNAME	PROC	NEAR
		;
		;WAS AN ALTERNATE NAME PROVIDED?
		;
		PUSHM	EDI,ESI

		MOV	ESI,OMF_NAME

		TEST	ESI,ESI
		JZ	L2$
		;
		;YEP, MOVE IT TO SYMBOL_LENGTH
		;
		CALL	FIX_RESNAM
		JMP	L3$

L2$:
		MOV	ESI,_OUTFILE_GINDEX
		CONVERT	ESI,ESI,OUTFILE_GARRAY
		ASSUME	ESI:PTR OUTFILE_STRUCT

		MOV	ESI,[ESI]._OF_FILE_LIST_GINDEX
		CONVERT	ESI,ESI,_FILE_LIST_GARRAY
		ASSUME	ESI:PTR FILE_LIST_STRUCT

		ADD	ESI,FILE_LIST_STRUCT.FILE_LIST_NFN
		ASSUME	ESI:PTR NFN_STRUCT

		MOV	EAX,[ESI].NFN_PRIMLEN
		ADD	EAX,[ESI].NFN_EXTLEN		;INCLUDE EXTENSION

		ADD	ESI,[ESI].NFN_PATHLEN

		ADD	ESI,NFN_STRUCT.NFN_TEXT
		CALL	FIX_RESNAM_1
L3$:
		MOV	ESI,OFF SYMBOL_LENGTH		;FOR USE BY /IMPLIB
		MOV	EDI,OFF MODULE_NAME

		LODSD
		STOSD

		MOV	ECX,EAX
		REP	MOVSB

		XOR	EAX,EAX

		STOSD

		POPM	ESI,EDI

		RET

FIX_DLLNAME	ENDP


FIX_RESNAM	PROC	NEAR	PRIVATE
		;
		;
		;
		LODSD
FIX_RESNAM_1::
		MOV	EDI,OFF SYMBOL_LENGTH
		STOSD

		XCHG	EAX,ECX

		REP	MOVSB

		XCHG	EAX,ECX

		STOSD

		RET

FIX_RESNAM	ENDP


FIX_ENDING_NUL	PROC	NEAR
		;
		;LAST OBJECT IS ZERO LENGTH, DELETE IT...
		;
		PUSHM	EDI,ESI,EBX

		MOV	ESI,EAX
		XOR	ECX,ECX			;ASSURE BASE MISMATCH

		MOV	EDX,PREV_PEOBJECT_NUMBER
		MOV	EBX,PREV_PEOBJECT_GINDEX

		TEST	EBX,EBX
                JZ      L91$

		MOV	LAST_PEOBJECT_NUMBER,EDX
		MOV	LAST_PEOBJECT_GINDEX,EBX
L1$:
		CONVERT	ESI,ESI,SEGMOD_GARRAY
		ASSUME	ESI:PTR SEGMOD_STRUCT

		MOV	EDI,[ESI]._SM_BASE_SEG_GINDEX
		MOV	ESI,[ESI]._SM_NEXT_SEGMOD_GINDEX

		CMP	EDI,ECX
		JZ	L9$			;SKIP IF BASE SEGMENT MATCHES

		MOV	ECX,EDI
		CONVERT	EDI,EDI,SEGMENT_GARRAY
		ASSUME	EDI:PTR SEGMENT_STRUCT

		MOV	[EDI]._SEG_PEOBJECT_NUMBER,EDX
		MOV	[EDI]._SEG_PEOBJECT_GINDEX,EBX
L9$:
		TEST	ESI,ESI
		JNZ	L1$
L91$:
		POPM	EBX,ESI,EDI

		RET

FIX_ENDING_NUL	ENDP


SIZE_IMPORTS_OBJECT	PROC	NEAR
		;
		;
		;
		MOV	EAX,PE_IMPORTS_OBJECT_NUMBER
		XOR	EDX,EDX			;# OF REFERENCED SYMBOLS

		TEST	EAX,EAX
		JZ	L9$
		;
		;COUNT REFERENCED MODULES, AND REFERENCED EXPORTS PER MODULE
		;
		MOV	THUNK_OFFSET,EDX
		MOV	ESI,FIRST_IMPMOD_GINDEX

		JMP	L5$

L9$:
		RET

L1$:
		CONVERT	ESI,ESI,IMPMOD_GARRAY
		ASSUME	ESI:PTR IMPMOD_STRUCT

		MOV	EAX,[ESI]._IMPM_NAME_SYM_GINDEX
		MOV	[ESI]._IMPM_JREF_START,EDX

		MOV	EBX,THUNK_OFFSET
		XOR	ECX,ECX			;NAME TEXT LENGTH

		MOV	[ESI]._IMPM_THUNK_OFFSET_START,EBX
		CALL	HANDLE_BYNAMES

		MOV	[ESI]._IMPM_NAME_SYM_GINDEX,EAX
		MOV	EAX,[ESI]._IMPM_ORD_SYM_GINDEX

		MOV	EBX,NAME_TEXT_SIZE
		CALL	HANDLE_BYORDS

		ADD	EBX,ECX
		MOV	[ESI]._IMPM_ORD_SYM_GINDEX,EAX

		MOV	NAME_TEXT_SIZE,EBX
		MOV	EAX,N_IMPORTS_REFERENCED

		SUB	EDX,EAX			;ANY REFERENCES?
		JZ	L4$

		MOV	ECX,N_MODULES_REFERENCED
		MOV	[ESI]._IMPM_N_IMPORTS,EDX	;# OF IMPORTS FROM THIS MODULE

		INC	ECX
		MOV	EAX,[ESI]._IMPM_LENGTH

		MOV	N_MODULES_REFERENCED,ECX
		MOV	ECX,N_IMPORTS_REFERENCED

		INC	EAX
		ADD	ECX,EDX

		MOV	N_IMPORTS_REFERENCED,ECX
		MOV	ECX,MODNAM_TEXT_SIZE

		SHL	EDX,2
		ADD	ECX,EAX

		MOV	EAX,THUNK_OFFSET
		ADD	EDX,4

		ADD	EAX,EDX
		MOV	MODNAM_TEXT_SIZE,ECX

		MOV	THUNK_OFFSET,EAX
L4$:
		MOV	ESI,[ESI]._IMPM_NEXT_GINDEX
		MOV	EDX,N_IMPORTS_REFERENCED
L5$:
		TEST	ESI,ESI
		JNZ	L1$

		MOV	ESI,PE_IMPORTS_OBJECT_GINDEX

		CONVERT	ESI,ESI,PE_OBJECT_GARRAY
		ASSUME	ESI:PTR PE_OBJECT_STRUCT

		MOV	DPTR [ESI]._PEOBJECT_NAME,'adi.'

		MOV	DPTR [ESI]._PEOBJECT_NAME+4,'at'
		;
		;NOW CALCULATE SIZE OF THIS SECTION
		;
		MOV	EDX,N_MODULES_REFERENCED
		MOV	EAX,SIZE PE_IMPORT_DIR_STRUCT+8	;TWO 4-BYTE NULL ENTRIES, PLUS A NULL BYTE AFTER MODULE NAME

		INC	EDX

		MUL	EDX

		MOV	EBX,EAX
		MOV	EAX,N_IMPORTS_REFERENCED

		SHL	EAX,3

		ADD	EAX,EBX

		ADD	EAX,NAME_TEXT_SIZE

		ADD	EAX,MODNAM_TEXT_SIZE

		ADD	EAX,3

		AND	AL,0FCH

		MOV	PEXEHEADER._PEXE_IMPORT_SIZE,EAX

		DO_FILE_ALIGN_EAX

		MOV	[ESI]._PEOBJECT_VSIZE,EAX
		CALL	DO_OBJECT_ALIGN

		MOV	EBX,PE_NEXT_OBJECT_RVA

		MOV	[ESI]._PEOBJECT_RVA,EBX
		ADD	EAX,EBX

		MOV	PEXEHEADER._PEXE_IMPORT_RVA,EBX
		MOV	PE_NEXT_OBJECT_RVA,EAX

		MOV	ESI,ICODE_SEGMOD_GINDEX
		CONVERT	ESI,ESI,SEGMOD_GARRAY
		ASSUME	ESI:PTR SEGMOD_STRUCT
		MOV	EAX,6

		MUL	N_IMPORTS_REFERENCED

		MOV	[ESI]._SM_LEN,EAX

		RET

SIZE_IMPORTS_OBJECT	ENDP


HANDLE_BYNAMES	PROC	NEAR	PRIVATE
		;
		;EAX IS SYMBOL GINDEX
		;ECX IS STRING LENGTHS
		;EDX IS # OF REFERENCED SYMBOLS
		;
		;RETURN
		;EAX IS FIRST REFERENCED SYMBOL
		;ECX IS UPDATED STRING LENGTHS
		;EDX IS UPDATED # OF REFERENCED SYMBOLS
		;
		TEST	EAX,EAX
		JZ	L99$

		PUSHM	EBP,EDI,ESI,EBX

		XOR	EDI,EDI

		MOV	FIRST_REF_GINDEX,EDI
L0$:
		MOV	ESI,EAX
		MOV	EBP,EAX

		TEST	EAX,EAX
		JZ	L9$

		CONVERT	ESI,ESI,SYMBOL_GARRAY
		ASSUME	ESI:PTR SYMBOL_STRUCT

		MOV	BL,[ESI]._S_REF_FLAGS
		MOV	EAX,[ESI]._S_IMP_NEXT_GINDEX

		AND	BL,MASK S_REFERENCED
		JZ	L0$

		INC	EDX			;COUNT REFERENCED SYMBOLS
		PUSH	EAX

		MOV	[ESI]._S_IMP_JREF_INDEX,EDX
		MOV	EAX,[ESI]._S_IMP_IMPNAME_GINDEX

		MOV	[ESI]._S_IMP_NEXT_GINDEX,0

		TEST	EDI,EDI
		JZ	L5$

		CONVERT	EDI,EDI,SYMBOL_GARRAY
		ASSUME	EDI:PTR SYMBOL_STRUCT

		MOV	[EDI]._S_IMP_NEXT_GINDEX,EBP
L59$:
		CONVERT	EAX,EAX,IMPNAME_GARRAY
		ASSUME	EAX:PTR IMPNAME_STRUCT
		MOV	EDI,[EAX]._IMP_LENGTH

		ADD	ECX,4
		POP	EAX

		ADD	ECX,EDI
		MOV	EDI,EBP

		AND	CL,0FEH
		JMP	L0$

L5$:
		MOV	FIRST_REF_GINDEX,EBP
		JMP	L59$


L9$:
		POPM	EBX,ESI,EDI,EBP

		MOV	EAX,FIRST_REF_GINDEX
L99$:
		RET

HANDLE_BYNAMES	ENDP


HANDLE_BYORDS	PROC	NEAR	PRIVATE
		;
		;EAX IS SYMBOL GINDEX
		;ECX IS STRING LENGTHS
		;EDX IS # OF REFERENCED SYMBOLS
		;
		;RETURN
		;EAX IS FIRST REFERENCED SYMBOL
		;ECX IS UPDATED STRING LENGTHS
		;EDX IS UPDATED # OF REFERENCED SYMBOLS
		;
		TEST	EAX,EAX
		JZ	L99$

		PUSHM	EBP,EDI

		XOR	EDI,EDI
		PUSH	ESI

		MOV	FIRST_REF_GINDEX,EDI
		PUSH	EBX

L0$:
		MOV	EBP,EAX
		MOV	ESI,EAX

		TEST	EAX,EAX
		JZ	L9$

		CONVERT	ESI,ESI,SYMBOL_GARRAY
		ASSUME	ESI:PTR SYMBOL_STRUCT

		MOV	BL,[ESI]._S_REF_FLAGS
		MOV	EAX,[ESI]._S_IMP_NEXT_GINDEX

		AND	BL,MASK S_REFERENCED
		JZ	L0$

		MOV	[ESI]._S_IMP_NEXT_GINDEX,0

		INC	EDX
		TEST	EDI,EDI

		MOV	[ESI]._S_IMP_JREF_INDEX,EDX
		JZ	L5$

		CONVERT	EDI,EDI,SYMBOL_GARRAY
		ASSUME	EDI:PTR SYMBOL_STRUCT

		MOV	[EDI]._S_IMP_NEXT_GINDEX,EBP
L59$:
		MOV	EDI,EBP

		JMP	L0$


L9$:
		POPM	EBX,ESI,EDI,EBP

		MOV	EAX,FIRST_REF_GINDEX
L99$:
		RET


L5$:
		MOV	FIRST_REF_GINDEX,EBP
		JMP	L59$

HANDLE_BYORDS	ENDP


DEFIMPS		PROC
		;
		;FIRST, DEFINE ICODE FOR EVERYONE TO USE
		;
		PUSHM	EDI,ESI,EBX
		MOV	ESI,ICODE_SEGMOD_GINDEX		;ZERO IF NOT PE OUTPUT

		TEST	ESI,ESI
		JZ	L9$

		CONVERT	ESI,ESI,SEGMOD_GARRAY
		ASSUME	ESI:PTR SEGMOD_STRUCT

		MOV	EAX,[ESI]._SM_START
		MOV	ESI,[ESI]._SM_BASE_SEG_GINDEX

		SUB	EAX,6			;CAUSE INDEXES START WITH 1...
		MOV	ICODE_SM_BASE_SEG_GINDEX,ESI

		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT

		MOV	ICODE_SM_START,EAX
		MOV	EAX,[ESI]._SEG_PEOBJECT_NUMBER

		MOV	EDX,[ESI]._SEG_PEOBJECT_GINDEX
		MOV	ICODE_PEOBJECT_NUMBER,EAX

		MOV	EAX,[ESI]._SEG_OS2_FLAGS
		MOV	ICODE_PEOBJECT_GINDEX,EDX

		MOV	ICODE_OS2_FLAGS,EAX
		;
		;NOW SCAN AND DEFINE SYMBOLS...
		;
		MOV	EAX,PE_IMPORTS_OBJECT_NUMBER

		TEST	EAX,EAX
		JZ	L9$

		MOV	EDI,ICODE_PEOBJECT_GINDEX
		MOV	ESI,FIRST_IMPMOD_GINDEX

		JMP	L5$

L1$:
		CONVERT	ESI,ESI,IMPMOD_GARRAY
		ASSUME	ESI:PTR IMPMOD_STRUCT

		MOV	EAX,[ESI]._IMPM_NAME_SYM_GINDEX
		CALL	HANDLE_OFFSETS

		MOV	EAX,[ESI]._IMPM_ORD_SYM_GINDEX
		CALL	HANDLE_OFFSETS

		MOV	ESI,[ESI]._IMPM_NEXT_GINDEX
L5$:
		TEST	ESI,ESI
		JNZ	L1$

		ADD	ICODE_SM_START,6

L9$:
		POPM	EBX,ESI,EDI

		RET


DEFIMPS		ENDP


HANDLE_OFFSETS	PROC	NEAR
		;
		;
		;
		TEST	EAX,EAX
		JZ	L99$
L1$:
		CONVERT	EAX,EAX,SYMBOL_GARRAY
		ASSUME	EAX:PTR SYMBOL_STRUCT

		MOV	ECX,[EAX]._S_IMP_JREF_INDEX
		MOV	EDX,ICODE_SM_START

		ADD	ECX,ECX
		MOV	[EAX]._S_OS2_NUMBER,EDI

		ADD	EDX,ECX
		ADD	ECX,ECX

		ADD	EDX,ECX

		MOV	[EAX]._S_OFFSET,EDX
		MOV	EAX,[EAX]._S_IMP_NEXT_GINDEX
L8$:
		TEST	EAX,EAX
		JNZ	L1$
L99$:
		RET

HANDLE_OFFSETS	ENDP


GET_NEW_OBJECT	PROC
		;
		;
		;
		PUSH	EDI
		MOV	EAX,SIZEOF PE_IOBJECT_STRUCT

		TILLP2_POOL_ALLOC

		MOV	EDI,EAX
		MOV	EDX,EAX

		MOV	ECX,SIZEOF PE_IOBJECT_STRUCT/4
		XOR	EAX,EAX

		REP	STOSD

		MOV	EAX,LAST_PEOBJECT_NUMBER
		MOV	ECX,LAST_PEOBJECT_GINDEX

		MOV	PREV_PEOBJECT_NUMBER,EAX
		MOV	PREV_PEOBJECT_GINDEX,ECX

		TEST	EAX,EAX
		JZ	L7$

		MOV	[ECX].PE_IOBJECT_STRUCT._PEOBJECT_NEXT_GINDEX,EDX
L8$:
		INC	EAX

		MOV	ECX,EDX
		MOV	LAST_PEOBJECT_NUMBER,EAX

		MOV	[EDX].PE_IOBJECT_STRUCT._PEOBJECT_NUMBER,EAX
		POP	EDI

		MOV	LAST_PEOBJECT_GINDEX,ECX

		RET

L7$:
		MOV	FIRST_PEOBJECT_GINDEX,EDX
		JMP	L8$


GET_NEW_OBJECT	ENDP


		.DATA?

		ALIGN	4

CURN_SEGMOD		DD	?
LAST_SEGMOD		DD	?
FIRST_REF_GINDEX	DD	?
THUNK_OFFSET		DD	?
PREV_PEOBJECT_NUMBER	DD	?
PREV_PEOBJECT_GINDEX	DD	?

endif

		END

